package com.feituan.wx.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.feituan.core.error.SystemCode;
import com.feituan.core.exception.BusinessException;
import com.feituan.core.persistence.service.IMemberAmountService;
import com.feituan.core.persistence.service.IMemberCouponService;
import com.feituan.core.persistence.service.IRechargeRecordService;
import com.feituan.core.persistence.service.IUserCouponService;
import com.feituan.core.persistence.service.IUserService;
import com.feituan.core.pojo.entity.MemberCoupon;
import com.feituan.core.pojo.entity.RechargeRecord;
import com.feituan.core.pojo.entity.User;
import com.feituan.core.pojo.request.CouponAndCount;
import com.feituan.core.pojo.request.UserCouponSendReq;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.service.WxPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 充值记录
 */
@Service
public class NewRechargeRecordService {

    private final static Logger logger = LoggerFactory.getLogger(NewRechargeRecordService.class);

    @Resource
    private IUserService userService;

    @Resource
    private WxPayService wxPayService;

    @Resource
    private IRechargeRecordService rechargeRecordService;

    @Resource
    private IMemberCouponService memberCouponService;

    @Resource
    private IUserCouponService userCouponService;




    public WxPayUnifiedOrderV3Result.JsapiResult pay(RechargeRecord rechargeRecord, HttpServletRequest request) {

        if (!rechargeRecord.getStatus().equals(1)) {
            throw new RuntimeException("支付失败，订单状态不为未支付");
        }
        User user = userService.getBaseMapper().selectById(rechargeRecord.getUserId());
        String openid = user.getWxid();
        WxPayUnifiedOrderV3Result.JsapiResult result = null;
        try {
            WxPayUnifiedOrderV3Request orderRequest = new WxPayUnifiedOrderV3Request();
            WxPayUnifiedOrderV3Request.Amount amount = new WxPayUnifiedOrderV3Request.Amount();
            // 元转成分
            int fee = 0;
            BigDecimal actualPrice = rechargeRecord.getPrice();
            fee = actualPrice.multiply(new BigDecimal(100)).intValue();
            orderRequest.setOutTradeNo(rechargeRecord.getNumber());
            amount.setTotal(fee);
            amount.setCurrency("CNY");
            orderRequest.setAmount(amount);
            orderRequest.setDescription("会员充值");
            WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer();
            payer.setOpenid(openid);
            orderRequest.setPayer(payer);
            // JSAPI返回方法
            result = wxPayService.createOrderV3(TradeTypeEnum.JSAPI, orderRequest);

        } catch (Exception e) {
            logger.error("prepay fail");
            e.printStackTrace();
            throw new BusinessException(SystemCode.PAY_PREPAY_ERROR);
        }

        return result;

    }


    @Transactional(rollbackFor = Exception.class)
    public void dtsPayNotify(WxPayNotifyV3Result.DecryptNotifyResult result) {
        String number = result.getOutTradeNo();
        String payId = result.getTransactionId();

        RechargeRecord rechargeRecord = rechargeRecordService.selectByNumber(number);
        // 分转化成元
        String totalFee = BaseWxPayResult.fenToYuan(result.getAmount().getTotal());

        // 检查支付订单金额
        if (!totalFee.equals(rechargeRecord.getPrice().toString())) {
            logger.error("微信付款成功或失败回调失败：{}", rechargeRecord.getNumber() + " : 支付金额不符合 totalFee=" + totalFee);
            throw new BusinessException(SystemCode.WX_PAY_NOTIFY_ERROR);
        }

        // 更新支付状态
        RechargeRecord record = new RechargeRecord();
        record.setId(rechargeRecord.getId());
        record.setStatus(2);
        record.setPayTime(new Date());
        record.setPayId(payId);
        rechargeRecordService.updateById(record);

        // 修改用户余额
        User userInfo = userService.selectById(rechargeRecord.getUserId());
        BigDecimal balance = userInfo.getBalance();

        User user = new User();
        user.setId(rechargeRecord.getUserId());
        user.setBalance(balance.add(new BigDecimal(totalFee)));
        userService.updateById(user);

        // 赠送用户优惠券
        LambdaQueryWrapper<MemberCoupon> qw = new LambdaQueryWrapper<>();
        qw.eq(MemberCoupon::getMemberAmountId, rechargeRecord.getMemberAmountId());
        List<MemberCoupon> memberCoupons = memberCouponService.getBaseMapper().selectList(qw);

        UserCouponSendReq userCouponSendReq = new UserCouponSendReq();
        List<Long> userIdList = Arrays.asList(userInfo.getId());
        userCouponSendReq.setUserIdList(userIdList);
        List<CouponAndCount> couponAndCountList = new ArrayList<>();
        memberCoupons.forEach(el -> {
            CouponAndCount couponAndCount = new CouponAndCount();
            couponAndCount.setCouponId(el.getCouponId());
            couponAndCount.setTotal(el.getTotal());
            couponAndCountList.add(couponAndCount);
        });
        userCouponSendReq.setCouponAndCountList(couponAndCountList);
        userCouponService.sendCoupon(userCouponSendReq);

    }
}
